﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace genGlues
{
    public class App
    {
        public static void PrintHelp()
        {
            Console.WriteLine("\ngenGlues: a wrapper for DNAWordLibrary \nBy Curtis Wang\n");
            Console.WriteLine("Usage: genGlues <mode> <output type> <mode parameters>");
            Console.WriteLine("where <output type> can be --html or --console");
            Console.WriteLine("\nExample: genGlues --c1to6 --html 1 2 3 4 5 6 7");
            Console.WriteLine("\nThe following show the different parameters in examples:");
            Console.WriteLine("--c1and4 --html n delta:float k1 k4");
            Console.WriteLine("--c1to6 --html n delta:float k1 k2 k3 k4 k5 k6");
            Console.WriteLine("--c1to7 --html n delta:float k1 k2 k3 k4 k5 k6 y");
            Console.WriteLine("--c1to8A --html n delta:float k1 k2 k3 k4 k5 k6 y d");
            Console.WriteLine("--c1to8B --html n delta:float k1 k2 k3 k4 k5 k6 gamma:float d");
        }

        static int Main(string[] args)
        {
            // supply version information and help
            if (args.Length == 0)
            {
                PrintHelp();
                return 1;
            }
            if (!((args[1] == "--html") || (args[1] == "--console")))
            {
                PrintHelp();
                return 1;
            } 
            // we'll do a sub-machine for each of the different modes in our switch
            int result = 0;
            switch (args[0])
            {
                case "--c1and4":
                    if (args.Length != 6)
                    {
                        PrintHelp();
                        return 1;
                    }
                    result = Functions.c1and4(args);
                    break;
                case "--c1to6":
                    result = Functions.c1to6(args);
                    break;
                case "--c1to7":
                    result = Functions.c1to7(args);
                    break;
                case "--c12378":
                    result = Functions.c12378(args);
                    break;
                case "--c1to8A":
                    result = Functions.c1to8A(args);
                    break;
                case "--c1to8B":
                    result = Functions.c1to8B(args);
                    break;
                default:
                    PrintHelp();
                    return 1;
            }
            if (result == 1)
            {
                PrintHelp();
                return 1;
            }
            return 0;

        }
    }

    /*
     * Console.WriteLine("--c1and4 --html n delta:float k1 k4");
     * Console.WriteLine("--c1to6 --html n delta:float k1 k2 k3 k4 k5 k6");
     * Console.WriteLine("--c1to7 --html n delta:float k1 k2 k3 k4 k5 k6 y");
     * Console.WriteLine("--c12378 --html n delta:float d k1 k2 k3 k4 gamma:double");
     * Console.WriteLine("--c1to8A --html n delta:float k1 k2 k3 k4 k5 k6 y d");
     * Console.WriteLine("--c1to8B --html n delta:float k1 k2 k3 k4 k5 k6 gamma:float d");
     */
    class Functions
    {
        public static int c1and4(string[] args)
        {
            Console.WriteLine("number of words is: {0}", int.Parse(args[2]));
            int l = getL(float.Parse(args[3]), int.Parse(args[2]), int.Parse(args[4]), int.Parse(args[5]));
            Console.WriteLine("optimal L is: {0}", l);
            char[][] output = dnaTools.outputAT(int.Parse(args[2]), l, int.Parse(args[4]), int.Parse(args[5]));
            handleOutput(args, output);
            return 0;
        }

        public static int c1to6(string[] args)
        {
            Console.WriteLine("number of words is: {0}", int.Parse(args[2]));
            int l = getL(float.Parse(args[3]), int.Parse(args[2]), int.Parse(args[4]), int.Parse(args[5]));
            Console.WriteLine("optimal L is: {0}", l);
            char[][] output = dnaTools.outputCA(int.Parse(args[2]), l, int.Parse(args[4]), int.Parse(args[5]), int.Parse(args[6]), int.Parse(args[7]), int.Parse(args[8]), int.Parse(args[9]));
            handleOutput(args, output);
            return 0;
        }

        public static int c1to7(string[] args)
        {
            Console.WriteLine("number of words is: {0}", int.Parse(args[2]));
            int l = getL(float.Parse(args[3]), int.Parse(args[2]), int.Parse(args[4]), int.Parse(args[5]));
            Console.WriteLine("optimal L is: {0}", l);
            char[][] output = dnaTools.outputB(int.Parse(args[2]), l, int.Parse(args[4]), int.Parse(args[5]), int.Parse(args[6]), int.Parse(args[7]), int.Parse(args[8]), int.Parse(args[9]), double.Parse(args[10]));
            handleOutput(args, output);
            return 0;
        }

        public static int c12378(string[] args)
        {
            Console.WriteLine("number of words is: {0}", int.Parse(args[2]));
            int l = getL(float.Parse(args[3]), int.Parse(args[2]), int.Parse(args[4]), int.Parse(args[5]));
            Console.WriteLine("optimal L is: {0}", l);
            char[][] output = BreakRuns.RunBR(int.Parse(args[2]), l, int.Parse(args[4]), int.Parse(args[5]), int.Parse(args[6]), int.Parse(args[7]), int.Parse(args[8]), double.Parse(args[9]));
            handleOutput(args, output);
            return 0;
        }

        public static int c1to8A(string[] args)
        {
            Console.WriteLine("number of words is: {0}", int.Parse(args[2]));
            int l = getL(float.Parse(args[3]), int.Parse(args[2]), int.Parse(args[4]), int.Parse(args[5]));
            Console.WriteLine("optimal L is: {0}", l);
            char[][] output = dnaTools.outputC8A(int.Parse(args[2]), l, int.Parse(args[4]), int.Parse(args[5]), int.Parse(args[6]), int.Parse(args[7]), int.Parse(args[8]), int.Parse(args[9]), double.Parse(args[10]), int.Parse(args[11]));
            handleOutput(args, output);
            return 0;
        }

        // this one is going to be interesting
        public static int c1to8B(string[] args)
        {
            Console.WriteLine("number of words is: {0}", int.Parse(args[2]));
            int l = getL(float.Parse(args[3]), int.Parse(args[2]), int.Parse(args[4]), int.Parse(args[5]));
            Console.WriteLine("optimal L is: {0}", l);
            char[][] output = dnaTools.outputC8B(int.Parse(args[2]), l, int.Parse(args[4]), int.Parse(args[5]), int.Parse(args[6]), int.Parse(args[7]), int.Parse(args[8]), int.Parse(args[9]), double.Parse(args[10]), int.Parse(args[11]));
            handleOutput(args, output);
            return 0;
        }

        static void handleOutput(string[] args, char[][] words)
        {
            if (args[1] == "--html")
            {
                // parse into HTML
                string table = createTable(words);
                writeHtml(table);
            }
            else if (args[1] == "--console")
            {
                Console.Write("\n");
                for (int i = 0; i < words.Length; i++)
                {
                    Console.Write("Word " + (i + 1) + ": ");
                    for (int j = 0; j < words[i].Length; j++)
                    {
                        Console.Write(words[i][j]);
                    }
                    Console.Write("\n");
                }
            }
        }

        static int getL(float delta, int n, int k1, int k4)
        {
            double c1 = FSvars.c1(delta);
            double c_star = FSvars.c_star(c1);
            double c2 = FSvars.c2(c1,c_star);
            int k = FSvars.k(k1, k4);
            int l_star = FSvars.l_star(((float)n),((float)k),c1,c2);
            int l_opt = ExpCount.findOptimalL(n, l_star, k1, k4);
            return l_opt;
        }

        static string createTable(char[][] words)
        {
            string tableString = "<table>";
            for (int i = 0; i < words.Length; i++)
            {
                tableString+="<tr><td>Word " + (i+1) + ": &nbsp; 3'</td>";
                for (int j = 0; j < words[i].Length; j++)
                {
                    if (words[i][j] == 'A')
                        tableString += "<td style=\"background-color: #5050ff; padding: .3em; color: black;\">" + "A" + "</td>";
                    else if (words[i][j] == 'C')
                        tableString += "<td style=\"background-color: #e00000; padding: .3em; color: black;\">" + "C" + "</td>";
                    else if (words[i][j] == 'T')
                        tableString += "<td style=\"background-color: #e6e600; padding: .3em; color: black;\">" + "T" + "</td>";
                    else if (words[i][j] == 'G')
                        tableString += "<td style=\"background-color: #00c000; padding: .3em; color: black;\">" + "G" + "</td>";
                }
                tableString += "<td>5'</td></tr><tr><td>&nbsp;</td></tr>";
            }
            return tableString+"</table>";
        }


        static void writeHtml(string table)
        {
            string html = "<html><body>" + table + "</body></html";
            File.WriteAllText("output.html", html);
        }
    }
}
